package com.app.oral.handler

import com.app.oral.model.ExpressionAnswer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.apache.ibatis.type.BaseTypeHandler
import org.apache.ibatis.type.JdbcType
import org.apache.ibatis.type.MappedTypes
import java.sql.CallableStatement
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.SQLException

@MappedTypes(ExpressionAnswer::class)
class ExpressionAnswerTypeHandler : BaseTypeHandler<ExpressionAnswer>() {
    private val objectMapper: ObjectMapper = jacksonObjectMapper().apply {
        registerModule(JavaTimeModule())
    }

    @Throws(SQLException::class)
    override fun setNonNullParameter(ps: PreparedStatement, i: Int, parameter: ExpressionAnswer, jdbcType: JdbcType?) {
        ps.setString(i, objectMapper.writeValueAsString(parameter))
    }

    @Throws(SQLException::class)
    override fun getNullableResult(rs: ResultSet, columnName: String): ExpressionAnswer? {
        val json = rs.getString(columnName)
        return parse(json)
    }

    @Throws(SQLException::class)
    override fun getNullableResult(rs: ResultSet, columnIndex: Int): ExpressionAnswer? {
        val json = rs.getString(columnIndex)
        return parse(json)
    }

    @Throws(SQLException::class)
    override fun getNullableResult(cs: CallableStatement, columnIndex: Int): ExpressionAnswer? {
        val json = cs.getString(columnIndex)
        return parse(json)
    }

    private fun parse(json: String?): ExpressionAnswer? {
        if (json.isNullOrBlank()) return null
        return try { objectMapper.readValue(json, ExpressionAnswer::class.java) } catch (e: Exception) { null }
    }
}

